﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BuscoPre.Domain;
using BuscoPre.Domain.Services;
using BuscoPre.Repository.MLA;
using BuscoPre.Repository.MLA.JsonTypes;

namespace BuscoPre.Repository
{
	public class ArticleDao
	{
		private static readonly string HotItemRequestUrl = "https://api.mercadolibre.com/sites/MLA/hot_items/search?limit=";
		private static readonly string SearchItemRequestUrl = "https://api.mercadolibre.com/sites/MLA/search?limit={0}&q={1}";
		private static readonly string SearchItemByCategoryIdRequestUrl = "https://api.mercadolibre.com/sites/MLA/search?category={0}&limit={1}";
		private static readonly string CategoryKey = "category";

		public static SearchResponse GetArticlesByCategory(int limit, string categoryId, string titleUrlRequest)
		{
			try
			{
				var q = string.Format(SearchItemByCategoryIdRequestUrl, categoryId, limit);

				GenericRestMessageService<Article> service = new SearchItemRestMessageService();
				var response = service.Get(q);

				if (response != null)
				{
					var searchResponse = new SearchResponse();
					searchResponse.AvailableCategories = new List<Category>();
					searchResponse.Category = new Category();
					searchResponse.Keywords = new StringBuilder();
					// La respuesta se obtiene a un SearchResult creado por la herramienta.
					var results = new SearchResult(response.ToString());

					// Obtiene los productos que matchean y genera las keywords de esta categoría.
					var matchingCatalog = results.MatchingCatalogProducts;

					if (matchingCatalog != null)
					{
						var it = matchingCatalog.GetEnumerator();

						if (it.MoveNext())
						{
							var current = (MatchingCatalogProduct)it.Current;
							searchResponse.Keywords.Append(current.Title.ToLower());

							while (it.MoveNext())
							{
								if (!string.IsNullOrEmpty(current.Title))
									searchResponse.Keywords.Append(", ");
								current = (MatchingCatalogProduct)it.Current;
								if (!string.IsNullOrEmpty(current.Title))
									searchResponse.Keywords.Append(current.Title.ToLower());
							}
						}
					}

					// Obtener los filtros disponibles por categoria y subcategoria.
					var filter = results.Filters.Where(item => item.Id.Contains(CategoryKey)).FirstOrDefault();

					if (filter != null)
					{
						var category = filter.Values.FirstOrDefault();

						searchResponse.Category.Id = category.Id;
						searchResponse.Category.Name = category.Name;
					}

					var categories = results.AvailableFilters.Where(item => item.Id.Contains(CategoryKey)).FirstOrDefault();

					// Recorrer la categoria seleccionada, antes crear la seo-url-friendly. Ademas puede servir para ir generando el tree sitepath.
					if (categories != null && categories.Values != null)
					{
						foreach (var value in categories.Values)
						{
							var category = new Category();
							category.Id = value.Id;
							category.Name = value.Name;
							var categoryUrl = FriendlyUrl.TitleToSeoURL(value.Name);
							category.Url = string.Concat(titleUrlRequest, "-", categoryUrl, "/", value.Id);
							category.Results = value.Results;
							searchResponse.AvailableCategories.Add(category);
						}
					}

					// Hay datos y se pudo convertir a un Poco.					
					if (results != null)
					{
						// Articulos retornados por la API.
						var articles = new List<Article>();
						foreach (var item in results.Results)
						{
							var article = new Article
							{
								Id = item.Id,
								Title = item.Title,
								Price = item.Price,
								Permalink = item.Permalink,
								Subtitle = item.Subtitle,
								Thumbnail = item.Thumbnail
							};
							articles.Add(article);
						}
						searchResponse.Articles = articles;
					}

					return searchResponse;
				}

				return null;
			}
			catch (Exception)
			{
				throw;
			}
		}

		public static List<Article> GetArticlesByQuery(string query, int limit)
		{
			try
			{
				var q = string.Format(SearchItemRequestUrl, limit.ToString(), query);

				GenericRestMessageService<Article> service = new SearchItemRestMessageService();
				var response = service.Get(q);

				if (response != null)
				{
					// La respuesta se obtiene a un SearchResult creado por la herramienta.
					var results = new SearchResult(response.ToString());

					if (results != null)
					{
						var articles = new List<Article>();
						foreach (var item in results.Results)
						{
							var article = new Article
							{
								Id = item.Id,
								Title = item.Title,
								Price = item.Price,
								Permalink = item.Permalink,
								Subtitle = item.Subtitle,
								Thumbnail = item.Thumbnail
							};
							articles.Add(article);
						}
						return articles.OrderBy(item => item.Title).ToList();
					}
				}

				return null;
			}
			catch (Exception)
			{

				throw;
			}
		}


		public static List<Article> GetHotItems(int limit)
		{
			try
			{
				string fullRequestUrl = string.Concat(HotItemRequestUrl, limit.ToString());
				//var response = RestMessageService.Get(fullRequestUrl);
				GenericRestMessageService<Article> service = new HotItemsRestMessageService();
				var response = service.Get(fullRequestUrl);

				if (response != null)
				{
					var articles = new List<Article>();
					var hotItems = new HotItemResult(response.ToString());

					foreach (var item in hotItems.Results)
					{
						var article = new Article
						{
							Id = item.Id,
							Title = item.Title,
							Price = item.Price,
							Permalink = item.Permalink,
							Subtitle = item.Subtitle,
							Thumbnail = item.Thumbnail
						};
						articles.Add(article);
					}
					return articles.OrderBy(item => item.Title).ToList();

					
				}
				return null;
			}
			catch (Exception)
			{
				throw;
			}

		}
	}
}
